package com.laker.autotest.webui.dev;

import cn.hutool.core.collection.CollUtil;
import com.laker.autotest.webui.utils.PlaywrightUtil;
import com.microsoft.playwright.*;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.nio.file.Paths;

/**
 * <p>
 * 脚本录制
 * 如果复用登录信息则启用
 * BrowserContext context = browser.newContext(new Browser.NewContextOptions()
 * // 加载cookie和localstorage, 模拟登录态
 * .setStorageStatePath(Paths.get("auth.json")));
 * 设置录制时窗口最大化，默认是1280x720
 * 1.BrowserType.LaunchOptions()  .setArgs(CollUtil.newArrayList("--start-maximized"))
 * 2.BrowserType.LaunchOptions()  .setHeadless(false)
 * 3.new Browser.NewContextOptions() .setViewportSize(null)
 * </p>
 */
@Slf4j
public class Record {

    /**
     * 是否复用已保存的登录状态（从auth.json加载）
     * true: 从auth.json加载cookie和localStorage，跳过登录步骤
     * false: 从空白状态开始，需要手动登录
     */
    private static final boolean REUSE_STORAGE_STATE = true;

    /**
     * 是否在录制结束后保存登录状态到auth.json
     * true: 保存当前浏览器的cookie和localStorage到auth.json，供下次复用
     * false: 不保存状态
     */
    private static final boolean SAVE_STORAGE_STATE = true;

    /**
     * 存储状态文件路径
     */
    private static final String STORAGE_STATE_PATH = "auth.json";

    public static void main(String[] args) {
        PlaywrightUtil.installBrowser("chromium");
        try (Playwright playwright = PlaywrightUtil.initPlaywright()) {
            BrowserType chromium = playwright.chromium();
            // Make sure to run headed.
            Browser browser = chromium.launch(new BrowserType.LaunchOptions()
                    .setArgs(CollUtil.newArrayList("--start-maximized"))
                    // 开启开发者模式
                    // 可以在开发者控制台使用 playwright对象中的任何方法调试，例如常见的元素定位
//                    .setDevtools(true)
                    .setHeadless(false));

            // Setup context however you like.
            Browser.NewContextOptions contextOptions = new Browser.NewContextOptions()
                    .setViewportSize(null);

            // 如果启用状态复用，则加载已保存的登录状态
            if (REUSE_STORAGE_STATE) {
                File storageFile = new File(STORAGE_STATE_PATH);
                if (storageFile.exists()) {
                    log.info("复用登录状态: {}", STORAGE_STATE_PATH);
                    contextOptions.setStorageStatePath(Paths.get(STORAGE_STATE_PATH));
                } else {
                    log.warn("未找到登录状态文件: {}，将从空白状态开始录制。首次录制完成后会自动保存登录状态。", STORAGE_STATE_PATH);
                }
            } else {
                log.info("未启用状态复用，将从空白状态开始录制");
            }

            BrowserContext context = browser.newContext(contextOptions);
            context.route("**/*", Route::resume);

            // Pause the page, and start recording manually.
            Page page = context.newPage();

            try {
                page.pause();
                log.info("录制完成，正在保存状态...");
            } catch (Exception e) {
                // 捕获用户关闭浏览器或其他录制过程中的异常
                log.warn("录制过程中发生异常: {}，仍将尝试保存登录状态", e.getMessage());
            } finally {
                // 无论是否发生异常，都尝试保存状态（如果启用了保存功能）
                if (SAVE_STORAGE_STATE) {
                    try {
                        File storageFile = new File(STORAGE_STATE_PATH);
                        context.storageState(new BrowserContext.StorageStateOptions().setPath(Paths.get(STORAGE_STATE_PATH)));
                        log.info("登录状态已保存到: {}", storageFile.getAbsolutePath());
                    } catch (Exception saveException) {
                        log.error("保存登录状态失败: {}", saveException.getMessage(), saveException);
                    }
                } else {
                    log.info("未启用状态保存，录制结束后不会保存登录状态");
                }
            }
        }
    }
}
